/**
 * 同步间隔执行函数
 * @param {Function} fun 返回Promsie的函数
 * @param {number} duration 时间间隔周期,默认2000
 * @param {boolean} imediate 是否立马开始
 */
export function timeOut (fun: Function, duration = 2000, imediate = false, maxTimes = 300) {
  let id: any
  let count = 0
  let stop = false
  /**内部轮询函数 */
  function _timeOut () {
    id = setTimeout(() => {
      if (stop) return
      if (count >= maxTimes) {
        return clear()
      }
      fun(clear)
      count++
      _timeOut();
    }, duration);
  }
  imediate && (fun(clear))
  _timeOut()
  /**清除计时函数 */
  function clear () {
    console.log(`this is stop ${id}`)
    stop = true
    clearTimeout(id)
  }
  return clear
}
/**
 * 异步间隔执行函数
 * @param {Function} fun 返回Promsie的函数
 * @param {number} duration 时间间隔周期,默认2000
 * @param {boolean} imediate 是否立马开始
 * @returns
 */
export async function timeOutAsync (fun: {(params?: any): Promise<any>}, duration = 2000, imediate = false, maxTimes = 300) {
  let id: any
  let stoped = false
  let count = 0
  /**内部轮询函数 */
  function _timeOut () {
    if (count >= maxTimes) {
      return clear()
    }
    id = setTimeout(async () => {
      if (stoped) {
        return
      }
      await fun(clear)
      _timeOut()
    }, duration);
  }

  imediate && (await fun(clear))
  _timeOut()

  /**清除计时函数 */
  function clear () {
    clearTimeout(id)
    stoped = true
  }
  return clear
}

/**
 * 新的超时方法
 * @param params 入参
 * @param params.fn 回调函数，入参为stop方法
 * @param [params.interval] 函数调用间隔
 * @param [params.maxTimes] 最大调用次数，默认300
 * @param [params.imediate] 是否调用后立马执行一次fn
 * @returns 停止函数
 */
export const timeout2 = (params: {fn: Function, interval?: number, maxTimes?: number, imediate: boolean}) => {
  params = Object.assign({interval: 2000, maxtimes: 300, imediate: false}, params)
  return timeOut(params.fn, params.interval, params.imediate, params.maxTimes)
}

/**
 * 新的超时异步方法
 * @param params 入参
 * @param params.fn 回调函数，入参为stop方法，为异步函数（promise)
 * @param [params.interval] 函数调用间隔
 * @param [params.maxTimes] 最大调用次数，默认300
 * @param [params.imediate] 是否调用后立马执行一次fn
 * @returns 停止函数
 */
export const timeoutAsync2 = (params: {fn: {(params?: any): Promise<any>}, interval?: number, maxTimes?: number, imediate: boolean}) => {
  params = Object.assign({interval: 2000, maxtimes: 300, imediate: false}, params)
  return timeOutAsync(params.fn, params.interval, params.imediate, params.maxTimes)
}
